# -*- coding: utf-8 -*-

from time import time
from django.db import models
from core.models import BaseModel, CoreModel, table_prefix
from django.utils.translation import gettext_lazy as _
import reversion
from apps.sys.models import User


def timestamp_bug():
    return "BUG" + str(round(time() * 100000))


@reversion.register()
class Bug(CoreModel):
    product = models.ForeignKey(
        to="pms.Product",
        related_name="bug_set",
        on_delete=models.CASCADE,
        db_constraint=False,
        verbose_name="所属产品",
    )
    module = models.ForeignKey(
        to="pms.Module",
        related_name="bug_set",
        on_delete=models.CASCADE,
        db_constraint=False,
        verbose_name="父模块",
    )
    version = models.ForeignKey(
        to="pms.Version",
        related_name="bug_set",
        on_delete=models.CASCADE,
        db_constraint=False,
        verbose_name="影响版本",
    )
    tcs = models.ManyToManyField(
        to="tms.TestCase",
        related_name="bug_set",
        db_constraint=False,
        verbose_name="关联用例",
    )
    towner = models.ForeignKey(
        to="sys.User",
        related_name="bug_towner_set",
        on_delete=models.PROTECT,
        db_constraint=False,
        verbose_name="测试接口人",
    )
    downer = models.ForeignKey(
        null=True,
        blank=True,
        to="sys.User",
        related_name="bug_downer_set",
        on_delete=models.PROTECT,
        db_constraint=False,
        verbose_name="开发接口人",
    )
    related_bugs = models.ManyToManyField(
        to="self",
        symmetrical=False,
        verbose_name="关联缺陷",
    )
    number = models.CharField(
        unique=True, max_length=128, default=timestamp_bug, verbose_name="缺陷编号"
    )
    name = models.CharField(max_length=128, verbose_name="缺陷名称")
    type = models.CharField(max_length=50, default="0", verbose_name="缺陷类型")
    priority = models.CharField(max_length=50, default="0", verbose_name="优先级")
    gravity = models.CharField(max_length=50, default="0", verbose_name="严重性")
    description = models.TextField(verbose_name="缺陷描述")

    resolved_time_expected = models.DateTimeField(
        null=True, blank=True, verbose_name="期望解决时间"
    )
    resolved_type = models.CharField(max_length=50, blank=True, verbose_name="解决类型")
    resolved_time = models.DateTimeField(
        null=True, blank=True, verbose_name="实际解决时间"
    )
    resolved_version = models.ForeignKey(
        null=True,
        blank=True,
        to="pms.Version",
        related_name="bug_resolved_set",
        on_delete=models.CASCADE,
        db_constraint=False,
        verbose_name="解决版本",
    )
    closed_time = models.DateTimeField(null=True, blank=True, verbose_name="关闭时间")

    def save(self, *args, **kwargs):
        if self.pk:
            original = Bug.objects.filter(id=self.pk).first()
            if original:
                if original.status == self.status:
                    self._log_status_change(
                        operation="UPDATE",
                        description=f"版本 #{self.prefix}",
                        operator=User.objects.get(id=self.modifier),
                    )
            else:
                self._log_status_change(operation="CREATE", operator=self.creator)

        super().save(*args, **kwargs)

    def _log_status_change(
        self, operation=None, description="", extras={}, operator=None
    ):
        if operation:
            BugOperate.objects.create(
                bug=self,
                operation=operation,
                description=description,
                extras=extras,
                creator=operator,
            )

    class Meta:
        db_table = table_prefix + "tms_bug"
        verbose_name = "缺陷管理"
        verbose_name_plural = verbose_name
        ordering = ("-create_time",)

    def __str__(self) -> str:
        return self.number


class BugOperate(BaseModel):
    OPERATION_CHOICES = (
        ("CREATE", "新建"),
        ("UPDATE", "修改"),
        ("ACTIVATE", "激活"),
        ("RESOLVE", "解决"),
        ("VERIFY", "验证"),
        ("SUSPEND", "挂起"),
    )
    bug = models.ForeignKey(
        to="Bug",
        related_name="bug_operate_set",
        on_delete=models.CASCADE,
        db_constraint=False,
        verbose_name="缺陷信息",
    )
    operation = models.CharField(
        max_length=50, choices=OPERATION_CHOICES, verbose_name="操作"
    )
    description = models.TextField(default="", verbose_name="描述信息")
    extras = models.JSONField(default=dict, verbose_name="扩展信息")

    class Meta:
        db_table = table_prefix + "tms_bug_operate"
        verbose_name = "缺陷操作管理"
        verbose_name_plural = verbose_name
        ordering = ("-create_time",)


class BugComment(BaseModel):
    bug = models.ForeignKey(
        to="Bug",
        related_name="bug_comment_set",
        on_delete=models.CASCADE,
        db_constraint=False,
        verbose_name="缺陷信息",
    )
    content = models.TextField(default="", verbose_name="评论信息")

    class Meta:
        db_table = table_prefix + "tms_bug_comment"
        verbose_name = "缺陷评论管理"
        verbose_name_plural = verbose_name
        ordering = ("-create_time",)
